package com.bs.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bs.enums.OrderStatus;
import com.bs.exception.BusinessException;
import com.bs.model.Item;
import com.bs.model.Order;
import com.bs.model.OrderItem;
import com.bs.model.User;
import com.bs.service.*;
import com.bs.vo.LoginVo;
import com.bs.vo.OrderCreateVo;
import com.bs.vo.OrderItemVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 说明：
 *
 * @author 琪
 * @since 2025/5/7 20:23
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<BaseMapper<Order>, Order> implements IOrderService {

    @Autowired
    private IOrderItemService orderItemService;

    @Autowired
    private IItemService itemService;

    @Autowired
    private IAuthService authService;

    @Autowired
    private IUserService userService;

    @Override
    public boolean save(Order entity) {
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        return super.save(entity);
    }

    @Override
    public boolean updateById(Order entity) {
        entity.setUpdateTime(new Date());
        return super.updateById(entity);
    }

    @Override
    public Order createOrder(OrderCreateVo createVo) throws BusinessException {
        String remark = createVo.getRemark();
        List<OrderItemVo> items = createVo.getItems();
        // 获取用户信息
        LoginVo loginVo = authService.getLoginUser();
        //  实现订单创建逻辑
        log.info("创建订单，商品列表：{}", items);
        // 商品列表转换为订单明细列表
        double totalPrice = 0;
        List<OrderItem> orderItems = new ArrayList<>();
        Map<String, Item> itemMap = new LinkedHashMap<>();
        for (OrderItemVo item : items) {
            //  检查商品是否存在
            Item itemData = itemService.getById(item.getItemId());
            if (itemData == null) {
                throw new RuntimeException("商品不存在,id: " + item.getItemId());
            }
            Integer quantityLeft = itemData.getQuantity();
            OrderItem orderItem = new OrderItem();
            orderItem.setItemId(item.getItemId());
            orderItem.setQuantity(item.getQuantity());
            Integer quantity = item.getQuantity();
            int left = quantityLeft - quantity;
            // 检查库存
            if (left < 0) {
                throw new RuntimeException(itemData.getName() + "库存不足!");
            }
            double itemAllPrice = itemData.getPrice() * quantity;
            orderItem.setPrice(itemAllPrice);
            orderItems.add(orderItem);
            // 统计订单总价格
            totalPrice += itemAllPrice;
            itemMap.put(itemData.getId(), itemData);
        }
        // 保存订单
        Order order = new Order();
        order.setUserId(loginVo.getUser().getId());
        order.setStatus(OrderStatus.CREATED);
        order.setTotalPrice(totalPrice);
        order.setRemark(remark);
        if (save(order)) {
            // 设置订单ID
            for (OrderItem orderItem : orderItems) {
                orderItem.setOrderId(order.getId());
            }
            // 保存订单明细
            for (OrderItem orderItem : orderItems) {
                orderItemService.save(orderItem);
            }
            // 减去商品库存
            for (OrderItem orderItem : orderItems) {
                String itemId = orderItem.getItemId();
                Integer quantity = orderItem.getQuantity();
                Item item = itemMap.get(itemId);
                Integer quantityLeft = item.getQuantity();
                int left = quantityLeft - quantity;
                item.setQuantity(left);
                itemService.updateById(item);
            }
            return order;
        }
        throw new RuntimeException("订单创建失败");
    }

    @Override
    public void cancelOrder(String orderId) throws BusinessException {

        // 获取用户信息
        LoginVo loginVo = authService.getLoginUser();
        // 查找订单
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        // 检查订单是否属于当前用户
        if (!order.getUserId().equals(loginVo.getUser().getId())) {
            throw new RuntimeException("订单不属于当前用户");
        }
        // 检查订单状态
        if (order.getStatus() != OrderStatus.CREATED) {
            throw new RuntimeException("订单状态不正确");
        }
        // 更新订单状态
        order.setStatus(OrderStatus.CANCELED);
        if (updateById(order)) {
            log.info("订单取消成功，订单ID：{}", orderId);
            // 恢复库存
            List<OrderItem> orderItems = orderItemService.listByOrderId(orderId);
            for (OrderItem orderItem : orderItems) {
                String itemId = orderItem.getItemId();
                Integer quantity = orderItem.getQuantity();
                Item item = itemService.getById(itemId);
                Integer quantityLeft = item.getQuantity();
                int left = quantity + quantityLeft;
                item.setQuantity(left);
                itemService.updateById(item);
            }
        }
    }

    @Override
    public void payOrder(String orderId) {
        // 获取用户信息
        LoginVo loginVo = authService.getLoginUser();
        // 查找订单
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        // 检查订单是否属于当前用户
        if (!order.getUserId().equals(loginVo.getUser().getId())) {

            throw new RuntimeException("订单不属于当前用户");

        }
        // 检查订单状态
        if (order.getStatus() != OrderStatus.CREATED) {
            throw new RuntimeException("订单状态不正确");
        }
        // 更新订单状态
        order.setStatus(OrderStatus.PAID);
        // 生成取餐码
        order.setOrderCode(Math.round(Math.random() * 10000) + "");
        if (updateById(order)) {
            // 实现订单支付逻辑
            log.info("订单支付成功，订单ID：{}", orderId);

        }
    }

    @Override
    public void waitingOrderCode(String orderId) {
        // 获取用户信息
        LoginVo loginVo = authService.getLoginUser();
        // 查找订单
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        // 检查订单是否属于当前用户
        //if (!order.getUserId().equals(loginVo.getUser().getId())) {
        //
        //    throw new RuntimeException("订单不属于当前用户");
        //
        //}
        // 检查订单状态
        if (order.getStatus() != OrderStatus.PAID) {
            throw new RuntimeException("订单状态不正确");
        }
        // 更新订单状态
        order.setStatus(OrderStatus.WAITING);
        // 生成取餐码
        order.setOrderCode(Math.round(Math.random() * 10000) + "");
        if (updateById(order)) {
            // 实现订单支付逻辑
            log.info("订单支付成功，订单ID：{}", orderId);

        }
    }

    @Override
    public void codeOrder(String orderId, String orderCode) {
        // 获取用户信息
        LoginVo loginVo = authService.getLoginUser();
        // 查找订单
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        // 检查订单状态
        if (order.getStatus() != OrderStatus.WAITING) {
            throw new RuntimeException("订单状态不正确");
        }
        if (!orderCode.equals(order.getOrderCode())) {
            throw new RuntimeException("取餐码不正确");
        }
        // 更新订单状态
        order.setStatus(OrderStatus.FINISHED);
        if (updateById(order)) {
            // 实现订单支付逻辑
            log.info("订单支付成功，订单ID：{}", orderId);

        }
    }

    @Override
    public List<Order> listOrder() {
        // 筛选当前用户的订单
        LoginVo loginUser = authService.getLoginUser();
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", loginUser.getUser().getId());

        List<Order> list = list(queryWrapper);
        // 按照订单创建时间倒序排序
        list.sort(Comparator.comparingLong(a -> a.getCreateTime().getTime()));
        ListUtil.reverse(list);
        for (Order order : list) {
            fillOrderItems(order);
        }

        // 无效的数据不返回（过滤数据库里的脏数据，一般不这样左，保证数据库不会出现脏数据。）
        list = list.stream().filter(e -> !e.getItems().isEmpty() && e.getTotalPrice() > 0).collect(Collectors.toList());

        // 填充用户名称
        fillUserName(list);

        return list;
    }

    @Override
    public List<Order> listOrderManage() {
        // 筛选当前用户的订单
        LoginVo loginUser = authService.getLoginUser();
        Boolean admin = loginUser.getUser().getAdmin();
        // 管理员可以查看所有订单
        if (!Boolean.TRUE.equals(admin)) {
            log.info("非管理员操作，权限不足");
            // throw new RuntimeException("权限不足");
        }
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();

        List<Order> list = list(queryWrapper);
        // 按照订单创建时间倒序排序
        list.sort(Comparator.comparingLong(a -> a.getCreateTime().getTime()));
        ListUtil.reverse(list);
        for (Order order : list) {
            fillOrderItems(order);
        }

        // 无效的数据不返回（过滤数据库里的脏数据，一般不这样左，保证数据库不会出现脏数据。）
        list = list.stream().filter(e -> !e.getItems().isEmpty() && e.getTotalPrice() > 0).collect(Collectors.toList());

        // 填充用户名称
        fillUserName(list);

        return list;
    }

    /**
     * 填充订单商品明细列表中的商品信息
     *
     * @param order 订单对象
     */
    private void fillOrderItems(Order order) {
        List<Item> items = new ArrayList<>();
        String id = order.getId();
        List<OrderItem> list = orderItemService.listByOrderId(id);
        for (OrderItem orderItem : list) {
            Item item = itemService.getById(orderItem.getItemId());
            item.setQuantity(orderItem.getQuantity());
            if (orderItem.getPrice() != null) {
                item.setPrice(orderItem.getPrice());
            }
            items.add(item);
        }
        order.setItems(items);
    }

    /**
     * 填充用户名称
     *
     * @param records 订单列表
     */
    private void fillUserName(List<Order> records) {
        List<String> userIdList = records
                // 学习对流式编程的使用 1
                .stream()
                // 转换: 数组中元素内容
                .map(Order::getUserId)
                // 过滤: 空的字符串
                .filter(StrUtil::isNotBlank)
                // 去重
                .distinct()
                // 收纳为新的数组
                .collect(Collectors.toList());
        if (userIdList.isEmpty()) {
            // userIdList为空,没有订单,没有用户,返回
            return;
        }
        List<User> users = userService.listByIds(userIdList);
        Map<String, String> userIdNameMap = users
                // 学习对流式编程的使用 2
                .stream()
                // 转换为Map对象
                .collect(Collectors.toMap(
                        // 返回Map的key
                        User::getId,
                        // 返回Map的value
                        User::getName
                ));
        records
                // 学习对流式编程的使用 3
                .forEach(record ->
                        // 遍历元素: 填充用户名称, 如果没有该用户, 填充为"匿名"用户
                        record.setUserName(userIdNameMap.getOrDefault(record.getUserId(), "匿名"))
                );
    }

}